import React,{useState,useEffect} from 'react';
import { ConfigProvider,message,Button,Table,Progress} from 'antd';
import { request } from './utils';
import type { UploadProps,GetProp,UploadFile } from 'antd';
import useEffectEvent from './useEffectEvent'
import './App.css';
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
const DEFAULT_SIZE = 1024 * 1024 * 100;
interface Part {
  chunk: Blob;
  size: number;
  filename?: string;
  chunk_name?: string;
  loaded?: number;
  percent?: number;
  xhr?: XMLHttpRequest
}

enum UploadStatus {
  INIT,
  PAUSE,
  UPLOADING,
  SUCCESS
}

function App() {
  let [currentFile, setCurrentFile] = useState<any>();
  const [hashPercentage, setHashPercentage] = useState(0)
  let [uploadStatus, setUploadStatus] = useState<UploadStatus>(UploadStatus.INIT);

  let [filename, setFilename] = useState<string>('');
  let [partList, setPartList] = useState<Part[]>([]);

  let [count,setCount] = useState(0);

  useEffect(()=>{
    // var t = true; 
    // setTimeout(function(){ t = false; }, 1000); 
    // while(t){ }
    // alert('end');
    
    console.log(123123213);
    return ()=>{
      ////组件销毁
    }
  },[]);

  // const onAdd=useHooks(()=>{
  //   setCount((c)=>c+1);
  // })

  // 计算文件hash
  const calculateHash=(partList: Part[])=> {
    return new Promise(function (resolve) {
      let worker = new Worker("/hash.js");
      console.log('worker', worker);
      worker.postMessage({ partList });
      console.log('partList-----------:',partList);
      worker.onmessage = function (event) {
        let { percent, hash } = event.data;
        setHashPercentage(percent);
        console.log('partList-----------:',percent);
        if (hash) {
          resolve(hash);
        }
      }
    });
  }

  // 选择文件
  const handleFileChange = (event:any) => {
    let file: File = event.target.files![0];
    setCurrentFile(file);
    ///
  }

  //文件切片
  const createChunks=(file: File)=>{
    let current = 0;
    let partList: Part[] = [];
    while (current < file.size) {
        let chunk: Blob = file.slice(current, current + DEFAULT_SIZE);
        partList.push({ chunk, size: chunk.size });
        current += DEFAULT_SIZE;
    }
    return partList;
  }

  const handleUpload=async()=>{
    if (!currentFile) {
      return message.error('你尚未选择文件');
    }
    // if (!allowUpload(currentFile)) {
    //     return message.error('不支持此类文件的上传');
    // }
    setUploadStatus(UploadStatus.UPLOADING);
    //分片上传
    let partList: Part[] = createChunks(currentFile);
    //先计算这个对象哈希值  秒传的功能 通过webworker子进程来去计算哈希
    let fileHash = await calculateHash(partList);
    let lastDotIndex = currentFile.name.lastIndexOf('.');//dog.jpg
    let extName = currentFile.name.slice(lastDotIndex);//.jpg
    let filename = `${fileHash}${extName}`;// hash.jpg
    console.log('fileHash', fileHash);

    setFilename(filename);
    partList.forEach((item: Part, index) => {
        item.filename = filename;
        item.chunk_name = `${filename}-${index}`;
        item.loaded = 0;
        item.percent = 0;
    });
    setPartList(partList);
    await uploadParts(partList, filename);
  }

  const handlePause=()=>{
    console.log('暂停')
    partList.forEach((part: Part) => part.xhr && part.xhr.abort());
    setUploadStatus(UploadStatus.PAUSE);
  }

  const handleResume=async()=>{
    setUploadStatus(UploadStatus.UPLOADING);
    await uploadParts(partList, filename);
  }

  function reset() {
    setUploadStatus(UploadStatus.INIT);
    setHashPercentage(0);
    setPartList([]);
    setFilename('');
  }

  let totalPercent = partList.length > 0 ? partList.reduce(
    (acc: number, curr: Part) => acc + curr.percent!, 0) / (partList.length * 100) * 100
    : 0

  const uploadParts=async(partList: Part[], filename: string)=>{
    console.log('uploadParts------start------');
    let { needUpload, uploadList } = await verify(filename);
    console.log('uploadParts------------:',needUpload,uploadList);
    if (!needUpload) {
        setUploadStatus(UploadStatus.SUCCESS);
        return message.success('秒传成功');
    }

    try {
        let requests = createHttp(partList, uploadList, filename);
        await Promise.all(requests);
        await request({ url: `/merge/${filename}` });

        message.success('上传成功');
        // reset();
        setUploadStatus(UploadStatus.SUCCESS);
    } catch (error) {
        message.error('上传失败或暂停');
        //uploadParts(partList, filename);
    }
  }

  const createHttp=(partList: Part[], uploadList: any, filename: string)=>{
    return partList.filter((part:any) => {
      let uploadFile = uploadList.find((item:any) => item.filename === part.chunk_name);
      if (!uploadFile) {
          part.loaded = 0;//已经上传的字节数0
          part.percent = 0;//已经上传的百分比就是0 分片的上传过的百分比
          return true;
      }
      if (uploadFile.size < part.chunk.size) {
          part.loaded = uploadFile.size;// 已经上传的字节数
          part.percent = Number((part.loaded / part.chunk.size * 100).toFixed(2));//已经上传的百分比
          return true;
      }
      return false;
    }).map((part: Part) =>{
      console.log('--------------part------1-----:',part);
      console.log('--------------part------2-----:',part.chunk.slice(part.loaded));
      return request({
        url: `/upload/${filename}/${part.chunk_name}/${part.loaded}`,//请求的URL地址
        method: 'POST',//请求的方法
        headers: { 'Content-Type': 'application/octet-stream' },//指定请求体的格式
        setXHR: (xhr: XMLHttpRequest) => part.xhr = xhr,
        onProgress: (event: ProgressEvent) => {
            part.percent = Number(((part.loaded! + event.loaded) / part.chunk.size * 100).toFixed(2));
            console.log('part.percent', part.chunk_name, part.percent);
            setPartList([...partList]);
        },
        data: part.chunk.slice(part.loaded) //请求体
      })
    })
  }

  const verify=async(filename: string)=>{
    return await request({
        url: `/verify/${filename}`,
    })
  }

  const columns = [
    {
        title: '切片名称',
        dataIndex: "filename",
        key: 'filename',
        width: '20%'
    },
    {
        title: '进度',
        dataIndex: "percent",
        key: 'percent',
        width: '80%',
        render: (value: number) => {
            return <Progress percent={value} />
        }
    }
  ]

  const onAdd=useEffectEvent(() => {
    setCount((c) => c + 1);
  });

  return (
    <ConfigProvider theme={{ token: { colorPrimary: '#00b96b' } }}>
      <div className="App">
        <h3>测试react-hooks</h3>
        <Button onClick={onAdd}>增加</Button>
        <p>{count}</p>
        <br />
        <input type="file" onChange={handleFileChange} placeholder='选择文件'/>
        <ul>
          <li>***********************************</li>
        </ul>
        {/* <Button type="primary" onClick={onGetFileHash}>生成文件hash</Button> */}
        <div className='hashbox'>
          <span>生成hash进度</span>
          <div><div style={{width:hashPercentage+'%'}}></div></div>
          {hashPercentage}%
        </div>
        {
            uploadStatus === UploadStatus.INIT && <Button type="primary" onClick={handleUpload} style={{ marginLeft: 10 }}>上传</Button>
        }
        {
            uploadStatus === UploadStatus.UPLOADING && <Button type="primary" onClick={handlePause} style={{ marginLeft: 10 }}>暂停</Button>
        }
        {
            uploadStatus === UploadStatus.PAUSE && <Button type="primary" onClick={handleResume} style={{ marginLeft: 10 }}>恢复</Button>
        }
        {
            uploadStatus === UploadStatus.SUCCESS && <Button type="primary" style={{ marginLeft: 10 }}>上传成功</Button>
        }
        <div className='hashbox'>
          <span>上传进度</span>
          <div><div style={{width:uploadStatus === UploadStatus.SUCCESS?'100%':totalPercent+'%'}}></div></div>
          {uploadStatus === UploadStatus.SUCCESS?'100%':totalPercent+'%'}
        </div>

        <Table
            columns={columns}
            dataSource={partList}
            rowKey={row => row.chunk_name!}
        />
      </div>
    </ConfigProvider>
  );
}

export default App;
